#include "FreeRTOS.h"
#include "task.h"
#include "stm32f4xx_hal.h"
#include "./stm32f401_pico_uart.h"
#include "./stm32f401_pico_led.h"
#include "./stm32f401_pico_key.h"
#include <stdio.h>
#include <string.h>

TaskHandle_t uart_task_handle = NULL;
extern char led_status_str[30];
extern char key_status_str[30];


UART_HandleTypeDef huart1;            // 串口句柄
//串口初始化：配置串口的TX（PA9）和RX（PA10）和其他设置
void MX_USART1_UART_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 使能GPIOA和UART时钟（PA9和PA10在GPIOA，串口在USART）
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_USART1_CLK_ENABLE();

    // TX引脚(PA9)配置
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    // RX引脚(PA10)配置
    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    //USAT参数配置
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        Error_Handler();
    }
}

int __io_putchar(int ch)
{
    HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);
    return (ch);
}

// 错误处理函数
void Error_Handler(void)
{
    while(1)
    {
        // 错误时可添加LED闪烁提示（例如PC13快速闪烁）
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
        HAL_Delay(100);
    }
}

// 定义链表节点结构
typedef struct Node {
    char data[30];
    struct Node* next;
} Node;

// 创建新节点
Node* createNode(const char* data) {
    Node* newNode = (Node*)pvPortMalloc(sizeof(Node));
    if (newNode == NULL) {
        printf("内存分配失败\n");
        return NULL;
    }
    strcpy(newNode->data, data);
    newNode->next = NULL;
    return newNode;
}

// 释放链表内存
void freeList(Node* head) {
    Node* temp;
    while (head != NULL) {
        temp = head;
        head = head->next;
        vPortFree(temp);
    }
}

// UART任务函数
void UART_Task(void* pvParameters) 
{
    uint8_t rx_char;  // 存储接收的字符
    Node* head = NULL;

    // 更新LED状态
    check_led_status();

    // 初始化链表（提前创建，也可在收到0后创建）
    head = createNode("LED状态未更新");
    head->next = createNode("KEY次数未更新");
    head->next->next = createNode("LED状态未更新");

    // 提示用户输入
    printf("请输入字符 '0' 以打印单链表...\r\n");

    for (;;) {
        // 更新LED状态
        check_led_status();

        // 更新KEY次数
        check_key_press();
        // 更新链表节点数据
        strcpy(head->data, led_status_str);
        strcpy(head->next->data, key_status_str);
        strcpy(head->next->next->data, led_status_str);

        // 阻塞等待接收1个字符（超时时间设为HAL_MAX_DELAY表示无限等待）
        HAL_UART_Receive(&huart1, &rx_char, 1, HAL_MAX_DELAY);

        // 判断是否收到字符'0'（ASCII码为48）
        if (rx_char == '0') {
            printf("\r\n收到字符'0'，开始打印单链表：\r\n");
            // 遍历链表并打印
            Node* current = head;
            while (current != NULL) {
                printf("节点数据: %s\r\n", current->data);
                current = current->next;
            }
            printf("单链表打印完成\r\n");
        } else {
            // 收到其他字符，提示重新输入
            printf("\r\n收到无效字符：%c，请输入'0'重试...\r\n", rx_char);
        }

        vTaskDelay(pdMS_TO_TICKS(100));  // 短暂延时，降低CPU占用
    }

    // 若任务退出，释放链表内存（实际中因for(;;)不会执行到这里）
    freeList(head);
}